package com.viknix.threadpool.manager.config.dump;

import com.viknix.threadpool.manager.cluster.core.ServerMemberManager;
import com.viknix.threadpool.manager.common.util.GroupKeyUtil;
import com.viknix.threadpool.manager.config.dump.engine.TpmDelayTaskExecuteEngine;
import com.viknix.threadpool.manager.config.dump.processor.DumpProcessor;
import com.viknix.threadpool.manager.config.dump.task.DumpTask;
import com.viknix.threadpool.manager.config.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: Dongqi
 * @Date: 2021/11/22 10:51
 * @Version 1.0
 * @Description: Dump data service.
 */
@Slf4j
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class DumpService {

    /**
     * full dump interval.
     */
    static final int DUMP_ALL_INTERVAL_IN_MINUTE = 6 * 60;

    /**
     * full dump delay.
     */
    static final int INITIAL_DELAY_IN_MINUTE = 6 * 60;

    /**
     * 任务处理器
     */
    private TaskManager dumpTaskMgr;

    private TaskManager dumpAllTaskMgr;

    private static final Logger LOGGER = LoggerFactory.getLogger(DumpService.class);

    static final AtomicInteger FINISHED = new AtomicInteger();

    static final int INIT_THREAD_COUNT = 10;

    int total = 0;

    private static final String TRUE_STR = "true";

    private static final String BETA_TABLE_NAME = "config_info_beta";

    private static final String TAG_TABLE_NAME = "config_info_tag";

    Boolean isQuickStart = false;

    private int retentionDays = 30;

    /**
     * 转储处理器
     */
    protected DumpProcessor processor;

    /**
     * 数据库交互
     */
    protected final ConfigService configService;

    /**
     * 集群节点管理中心
     */
    protected final ServerMemberManager memberManager;

    /**
     * 在这里你建设性地注入依赖对象，确保一些依赖功能提前初始化。
     *
     * @param configService
     * @param memberManager
     */
    public DumpService(ConfigService configService, ServerMemberManager memberManager) {
        this.configService = configService;
        this.memberManager = memberManager;
        this.processor = new DumpProcessor(this);
        this.dumpTaskMgr = new TaskManager("com.viknix.tpm.server.DumpTaskManager");
        this.dumpTaskMgr.setDefaultTaskProcessor(processor);
    }

    public ConfigService getConfigService() {
        return configService;
    }

    public void dump(String dataId, String group, String tenant, String tag, long lastModified, String handleIp) {
        dump(dataId, group, tenant, tag, lastModified, handleIp, false);
    }

    /**
     * 将 DumpTask 添加到 TaskManager，它将异步执行。
     *
     * @see TpmDelayTaskExecuteEngine
     */
    public void dump(String dataId, String group, String tenant, String tag, long lastModified, String handleIp,
                     boolean isBeta) {

        // dataId + group + tenant
        String groupKey = GroupKeyUtil.getKey(dataId, group, tenant);
        // dataId + group + tenant + isBeta + tag
        String taskKey = String.join("+", dataId, group, tenant, String.valueOf(isBeta), tag);
        // 将刷新配置的任务放到Map中
        dumpTaskMgr.addTask(taskKey, new DumpTask(groupKey, tag, lastModified, handleIp, isBeta));
        log.info("[dump-task] add task. groupKey={}, taskKey={}", groupKey, taskKey);
    }

    /**
     * Used to determine whether the aggregation task, configuration history cleanup task can be performed.
     *
     * @return {@link Boolean}
     */
    protected abstract boolean canExecute();
}
